<?php

namespace app\api\controller;

use app\admin\model\cms\MembershipExpiryRecordModel;
use app\admin\model\cms\OrderModel;
use app\admin\model\cms\Plate;
use app\admin\model\cms\Platepost;
use app\admin\model\cms\PlazaCategorymodel;
use app\admin\model\cms\PlazaPostModel;
use app\admin\model\UserGroup;
use app\common\controller\Api;
use app\common\model\Config;
use Endroid\QrCode\QrCode;
use think\Log;
use think\Model;
use think\Request;
use Yansongda\Pay\Pay;
use think\Db;

/**
 * 微信支付
 * 文档地址 https://pay.yansongda.cn/docs/v2/wechat/pay.html
 * 使用版本 2.x
 * Class WechatPay
 * @package app\api\controller
 */
class WechatPay extends Api
{
    //无需登录的方法,同时也就不需要鉴权了
    protected $noNeedLogin = ['wechatPayNotify','wechatMiniPay'];
    //无需鉴权的方法,但需要登录 *表示全部
    protected $noNeedRight = ['wechatNativePay'];

    public function _initialize()
    {
        parent::_initialize();
    }

    //微信支付配置项目
    public $config = [
        'wechatPay'=>[
            'appid' => '', // APP APPID()
            'app_id' => '', // 公众号 APPID（）
            'miniapp_id' => '', // 小程序 APPID()
            'mch_id' => '',//商户号
            'key' => '',//商户号秘钥
            'notify_url' => '',//微信支付异步回调 @todo 上线的时候吧测试域名改为正式服务器的域名 （https://fupanai.com）
            'cert_client' => '', // optional，退款等情况时用到
            'cert_key' => '',// optional，退款等情况时用到
            'log' => [ // optional
                'file' => 'login/wechat.log',
                'level' => 'debug', // 建议生产环境等级调整为 info，开发环境为 debug
                'type' => 'single', // optional, 可选 daily.
                'max_file' => 30, // optional, 当 type 为 daily 时有效，默认 30 天
            ],
            'http' => [ // optional
                'timeout' => 5.0,
                'connect_timeout' => 5.0,
                // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
            ],
            // 'mode' => 'dev', // optional, dev/hk;当为 `hk` 时，为香港 gateway。
        ],
    ];

    //初始化获取支付配置项参数
    public function init()
    {
        $config = Config::where('group','we_chat_pay')->select();//获取微信配置项
        //设置微信支付配置项
        foreach($config as $v){
            $this->config['wechatPay'][$v['name']] = $v['value'];
        }
    }

    //微信生成二维码支付
    public function wechatNativePay(Request $request)
    {
        $this->init();

        $order_id = $request->param('order_id') ?? '';
        $user = $this->auth->getUser();//用户信息

        if (!$order_id){
            $this->error('缺少参数');
        }
        //pay_type支付方式|1:微信,2:积分,3:临时申请订单(不用付费,只要后台管理员同意就行)
        $order = OrderModel::where('id',$order_id)->where('user_id',$user['id'])->where('pay_type',1)->find();//pay_status=0:尚未支付
        if(!$order || $order['price'] == 0){
            $this->error('订单信息不正确');
        }

        //订单已经支付
        if ($order['pay_status'] == 1){
            $this->error('订单已支付,请勿重复支付');
        }

        $this->config['wechatPay']['cert_client'] = APP_PATH . 'certificate.pem';
        $this->config['wechatPay']['cert_key'] = APP_PATH . 'private_key.pem';

        $body = Config::where('name','name')->value('value') ?? 'body';//获取网站名称
        $pay_data = [
            'out_trade_no' => $order['order_num'],//我方订单号
            'body' => $body,//支付title
            'total_fee' => $order['price'] * 100,//支付金额（单位：分）
//            'total_fee' => '1',//支付金额（单位：分）
        ];

        $pay = Pay::wechat($this->config['wechatPay'])->scan($pay_data);

        //将网址url转成二维码
        // 创建一个QR码实例
        $qrCode = new QrCode($pay['code_url']);
        // 设置二维码的大小、颜色等参数
        $qrCode->setSize(300);
        $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0]); // 设置前景色为黑色
        $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255]); // 设置背景色为白色

        // 将二维码保存为图片文件
        $qrCodePath = 'qrCodeImages/' . time(). '_' . rand(111,999) . '.png';
        $qrCode->writeFile($qrCodePath);

        //获取当前根域名
        $request = Request::instance();

        $res = [
            'code_url' => localurl($qrCodePath),
        ];
        $this->success('success', $res);
    }

    //微信小程序发起支付
    public function wechatMiniPay(Request $request){
        $this->init();

        $order_id = $request->param('order_id') ?? '';
        $user = $this->auth->getUser();//用户信息

        if (!$order_id){
            $this->error('缺少参数');
        }
        //pay_type支付方式|1:微信扫码支付,2:积分,3:临时申请订单(不用付费,只要后台管理员同意就行),4:管理员后台发放,5:微信小程序支付
        $order = OrderModel::where('id',$order_id)->where('user_id',$user['id'])->where('pay_type',5)->find();//pay_status=0:尚未支付
        if(!$order || $order['price'] == 0){
            $this->error('订单信息不正确');
        }

        //订单已经支付
        if ($order['pay_status'] == 1){
            $this->error('订单已支付,请勿重复支付');
        }

        $wechat_openid = \app\admin\model\User::where('id',$user['id'])->value('wechat_openid');
        if (!$wechat_openid){
            $this->error('缺少openid');
        }

        $this->config['wechatPay']['cert_client'] = APP_PATH . 'certificate.pem';
        $this->config['wechatPay']['cert_key'] = APP_PATH . 'private_key.pem';

        $body = Config::where('name','name')->value('value') ?? 'body';//获取网站名称
        $pay_data = [
            'out_trade_no' => $order['order_num'],//我方订单号
            'body' => $body,//支付title
            'total_fee' => $order['price'] * 100,//订单总金额，单位为分,
            'openid' => $wechat_openid,
        ];

        //拉起小程序支付
        $pay = Pay::wechat($this->config['wechatPay'])->miniapp($pay_data);
        $res =json_decode(json_encode($pay,true),true);
        $this->success('success', $res);
    }

    //支付成功异步回调
    public function wechatPayNotify()
    {
        $this->init();//初始化微信支付配置项

        $filePath = 'login/test.txt';
//        $date = date('Y-m-d H:i:s');
//        $data = "回调成功了-{$date}"; // 要写入的数据
//        file_put_contents($filePath, $data);

        $pay = Pay::wechat($this->config['wechatPay']);
        try {
            $data = $pay->verify(); // 是的，验签就这么简单！返回值为微信回调的订单数据

            //判断是否支付成功
            if ($data->return_code == "SUCCESS" && $data->result_code == "SUCCESS") {
                //支付成功
                //防止支付回调成功后重复给用户打款
                $order = OrderModel::where('order_num', $data->out_trade_no)->find();//查询我方订单号是否打款
                if ($order['pay_status'] == 1) {
                    //已经支付过了,通知微信停止异步回调
                    return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';//付款成功
                }

                $update_data = [
                    'pay_status' => 1,//订单支付状态|默认0:未支付,1:已支付
                    'pay_time' => date('Y-m-d H:i:s'),//用户付款时间
                    'pay_num' => $data->transaction_id,//第三方订单号
                    'cash_fee' => $data->cash_fee / 100,//用户实际支付金额(现金支付金额)
                ];
                //更新订单
                $time = time();
                $success_1 = OrderModel::where('id', $order['id'])->update($update_data);

//                file_put_contents($filePath,json_encode($success_1,true));

                if (!$success_1){
                    //Log::write("{order表id={$order['id']}在微信支付成功回调中更新失败" , 'error');//记录日志
                }
                //判断是否购买的是会员组
                if ($order['goods_type'] == 'user_group'){
                    $user = Db::name('user')->find($order['user_id']);

                    $user_group = UserGroup::where('id',$order['goods_id'])->find();
                    //判断会员分组的有效时长 0:无限天
                    if ($user_group['membership_expiry'] == 0){
                        $period_of_validity = 1;//有效期|1=长期有效,0=无效,毫秒时间戳=有效时间
                    }else{
                        $days = $user_group['membership_expiry']; // 指定的天数
                        //看当前会员是否过期 1=长期有效,0=无效,毫秒时间戳=有效时间
                        if ($user['period_of_validity'] > 1 || !$user['period_of_validity']){
                            if ($user['period_of_validity'] < time()){
                                $user['period_of_validity'] = 0;
                            }
                            // 计算指定天数后的时间戳 秒
                            $specifiedTimestamp = strtotime("+{$days} days", ($user['period_of_validity'] / 1000) > 0 ? : $time) * 1000;//毫秒
                            $period_of_validity = $user['period_of_validity'] + $specifiedTimestamp;//单位毫秒
                        }elseif($user['period_of_validity'] == 1){
                            $period_of_validity = 1;//会员有效期(到期时间)|1=长期有效,0=无效,毫秒时间戳=有效时间
                        }
                    }

                    $user_success = \app\admin\model\User::where('id',$order['user_id'])->update([
                        'group_id'=>$order['goods_id'],//会员组别id
                        'member_type'=>'member',//会员类型|tourist=游客,TrialMember=试用会员，member=正式会员'
                        'member_make_time'=>time(),//会员开通时间
                        'period_of_validity'=>$period_of_validity,//会员有效期(到期时间)|1=长期有效,0=无效,毫秒时间戳(13位)=有效时间
                    ]);
//                    $this->printLog($user_success);//打印记录到文件
                    if (!$user_success){
                        //Log::write("{user表id={$order['user_id']}微信回调成功,但更应用户信息失败" , 'error');//记录日志
                    }
                }else{
                    //购买分类/文章内容
                    $membership_Expiry_record_model = MembershipExpiryRecordModel::where('user_id',$order['user_id'])
                        ->where('goods_type',$order['goods_type'])
                        ->where('table_name',$order['table_name'])
                        ->where('goods_id',$order['goods_id'])
                        ->order('id','desc')
                        ->find();
                    //判断之前是否购买过
                    $expiration_time = 0;//剩余时长|没买过就默认为0
                    if ($membership_Expiry_record_model){
                        //是,时间叠加
                        $expiration_time = $membership_Expiry_record_model['expiration_time'] - $time;
                        if ($expiration_time <= 0){
                            $expiration_time = 0;
                        }
                    }
                    //获取订单所购买的会员时长(天)|0:无限天
                    $old_membership_duration = $order['membership_duration'] ?? 0;
                    if ($order['membership_duration']){
                        $old_membership_duration = $order['membership_duration'] * 24 * 60 *60 + $time;
                    }
//                创建
                    $data_2 = [
                        'user_id'=>$order['user_id'],
                        'order_id'=>$order['id'],
                        'goods_type'=>$order['goods_type'],
                        'table_name'=>$order['table_name'],
                        'goods_id'=>$order['goods_id'],
                        'membership_duration'=>$order['membership_duration'],
                        'expiration_time'=>$expiration_time + $old_membership_duration,
                    ];
                    $success_2 = MembershipExpiryRecordModel::create($data_2);//创建会员过期记录表,查询数据的时候每次获取最后一条
                    if (!$success_2){
                        //Log::write("{membership_expiry_record表order_id={$order['id']}在微信支付成功回调中创建失败" , 'error');//记录日志
                    }
                }
            }
        } catch (\Exception $exception) {
            //Log::write($exception->getMessage(), 'error');//记录日志
            $data = "错误-{$exception->getMessage()},行={$exception->getFile()},{$exception->getLine()}";
            //file_put_contents($filePath, $data);
        }
        $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
        return $str;
    }

    //打印记录
    private function printLog($msg){
        $filePath = 'login/test.txt';//保存路径是public/login/test.txt
//        $msg = json_encode($update_data,true) . "|order表id={$order['id']}|订单状态={$success_1}|membership_expiry={$user_group['membership_expiry']}|period_of_validity={$period_of_validity}|user_success={$user_success}";
        file_put_contents($filePath, $msg);//把内容写入文件
    }


}
